package com.zzyl.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.zzyl.config.JwtTokenManagerProperties;
import com.zzyl.constant.Constants;
import com.zzyl.dto.UserLoginRequestDto;
import com.zzyl.entity.Member;
import com.zzyl.mapper.MemberMapper;
import com.zzyl.service.MemberService;
import com.zzyl.service.WeChatService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description MebmerServiceImpl
 * @Author songyu
 * @Date 2024-10-20
 */
@Service
public class MemberServiceImpl implements MemberService {

    @Autowired
    private MemberMapper memberMapper;

    @Autowired
    private WeChatService weChatService;


    static List<String> DEFAULT_NICKNAME_PREFIX = Arrays.asList(
            "生活更美好",
            "大桔大利",
            "日富一日",
            "好柿开花",
            "柿柿如意",
            "一椰暴富",
            "大柚所为",
            "杨梅吐气",
            "天生荔枝"
    );

    @Autowired
    private JwtTokenManagerProperties jwtTokenManagerProperties;

    /**
     * 微信小程序登录方法
     *
     * @param userLoginRequestDto
     * @return
     */
    @Override
    public LoginVo login(UserLoginRequestDto userLoginRequestDto) {

        //1.远程调用根据登录授权码（userLoginRequestDto.getCode()）微信授权登录接口获取openId
        String openId = weChatService.getOpenId(userLoginRequestDto.getCode());

        //2.调用memberMapper根据openId查找member用用信息对象
        Member member = memberMapper.getByOpenId(openId);

        //3.判断用户信息是否为空，为空创建Member用户对象，封装openid
        if(ObjectUtil.isEmpty(member)){
            member = new Member();
            member.setOpenId(openId);
        }

        //4.远程调用根据手机号授权码（userLoginRequestDto.getPhoneCode()）微信获取手机号接口
        String phone = weChatService.getPhone(userLoginRequestDto.getPhoneCode());

        //5.插入或更新
        if(member.getId()!=null && !member.getPhone().equals(phone)) {
            //5.1 判断用户id不为空，并且获取的手机号与数据库查询到手机号不一致，封装最新的手机号再更新
            member.setPhone(phone);
            memberMapper.update(member);
        }else if(member.getId()==null) {
            //5.2 判断用户id为空进行插入操作
            //封装昵称(上面数组随机获取一个，并且拼接手机号后4位)
            String name = DEFAULT_NICKNAME_PREFIX.get((int) (Math.random()*DEFAULT_NICKNAME_PREFIX.size()))+
                    phone.substring(7);
            member.setName(name);
            //封装手机号
            member.setPhone(phone);
            //插入操作
            memberMapper.save(member);
        }

        //6.生成jwt令牌token
        //定义载荷
        Map<String, Object> claims = new HashMap<>();
        claims.put(Constants.JWT_USERID, member.getId());
        claims.put(Constants.JWT_USERNAME, member.getName());

        //生成token
        String token = JwtUtil.createJWT(jwtTokenManagerProperties.getBase64EncodedSecretKey(),
                jwtTokenManagerProperties.getTtl(), claims);
        //7.封装LoginVo对象（令牌和昵称）
        //LoginVo loginVo = new LoginVo();
        //loginVo.setToken(token);
        //loginVo.setNickName(member.getName());
        //建造者设计模式创建对象: 将创建对象的各个属性任意组合创建对象的方式就是建造者
        //    优势：创建对象更加灵活，可以采用链式编程
        //    语法：类.Builder().属性名1(值1).属性名2(值2)...build() 中间无论设置多少个属性值都会采用同一个构造函数创建对象，最终一个构造函数解决灵活创建对象
        //创建对象旧的方式：new的方式，需要创建很多构造函数才可以灵活创建对象
        //    new 对象()
        //    new 对象(属性值1)
        //    new 对象(属性值1，属性值2)
        //    new 对象(属性值1，属性值2,属性值3...)
        //8.返回loginVo
        return LoginVo.builder().token(token).nickName(member.getName()).build();
    }
}
